<script setup lang="ts">
import {
  NForm,
  NFormItem,
  NInput,
  type FormInst,
  NButton,
  NSelect,
  NDatePicker,
  type DataTableColumns,
  NDataTable,
  useDialog,
  NCollapse,
  NCollapseItem,
  type SelectOption,
  useMessage
} from 'naive-ui'
import { h, onDeactivated, onMounted, onUnmounted, ref, shallowRef } from 'vue'
import type {
  AddBatchModel,
  ClueSelectOptionModel,
  ClueBaseModel,
  CollectingTableRowModel
} from '@/api/batch'
import FixedAction from '@/components/FixedAction.vue'
import useRouteReplace from '@/hooks/useRouteReplace'
import type { HttpResponse, HttpResponsePagination } from '@/utils/http'
import { useRoute, useRouter } from 'vue-router'
import { sendRequest } from '@/utils/api'
import type { DicTreeModel } from '@/api/dic'
import { format } from 'date-fns'

const route = useRoute()
const router = useRouter()
const routeReplace = useRouteReplace(route.query.redirect as string)
const dialog = useDialog()
const message = useMessage()

const isEdit = route.params.id !== undefined

const checkEdit = async () => {
  if (!isEdit) return
  try {
    const [error, res] = await sendRequest({
      module: 'batch',
      api: 'formInfo',
      override: {
        params: {
          batchId: route.params.id
        }
      }
    })
    if (error) throw error
    if (res.code !== 0) throw new Error(res.msg)
    res.data.id = res.data.batchId
    if (res.data.startDate) {
      res.data.startDate = format(new Date(res.data.startDate), 'yyyy-MM-dd')
    }
    if (res.data.endDate) {
      res.data.endDate = format(new Date(res.data.endDate), 'yyyy-MM-dd')
    }
    formData.value = res.data
    handleClueNameVisible(false)
  } catch (error) {
    console.log(error)
  }
}

const clueOptions = shallowRef<ClueSelectOptionModel[]>([])
const clueOptionsLoading = ref(false)
const queryClueOptions = async () => {
  try {
    clueOptionsLoading.value = true
    const [error, res] = await sendRequest<HttpResponse<ClueSelectOptionModel[]>>({
      module: 'batch',
      api: 'clueList',
      override: {
        params: {
          batchId: route.params.id ?? null
        }
      }
    })
    if (error) throw error
    if (res.code !== 0) throw new Error(res.msg)

    clueOptions.value = res.data
  } catch (error) {
    console.log(error)
  } finally {
    clueOptionsLoading.value = false
  }
}

const formInst = shallowRef<FormInst | null>(null)
const formData = ref({} as AddBatchModel)
const submitLoading = ref(false)

const handleSubmit = () => {
  if (submitLoading.value) return
  formInst.value?.validate(async (error) => {
    if (error) return

    try {
      submitLoading.value = true
      const [error, res] = await sendRequest({
        module: 'batch',
        api: isEdit ? 'update' : 'add',
        override: {
          data: {
            ...formData.value,
            itemIds: [...new Set(tableData.value.map((e) => e.id))]
          }
        }
      })
      if (error) throw error
      if (res.code !== 0) throw new Error(res.msg)
      message.success(res.msg)
      window.flags.flushBatch = true
      routeReplace()
    } catch (error: any) {
      message.error(error.message)
    } finally {
      submitLoading.value = false
    }
  })
}

// const handleDelete = (id: number) => {
//   dialog.warning({
//     title: '确认删除？',
//     positiveText: '确认',
//     negativeText: '取消',
//     onPositiveClick: async () => {
//       deleteIds.value.push(id)
//     }
//   })
// }

const expandNames = ref<number[]>([])
const clueList = ref<ClueBaseModel[]>([])
const handleClueNameVisible = (v: boolean) => {
  if (!v) setClueBaseInfo()
}
const queryClueInfo = async (id: number): Promise<ClueBaseModel | null> => {
  try {
    clueOptionsLoading.value = true
    const [error, res] = await sendRequest<HttpResponse<ClueBaseModel>>({
      module: 'batch',
      api: 'clueBaseInfo',
      uri: {
        id
      }
    })
    if (error) throw error
    if (res.code !== 0) throw new Error(res.msg)
    return res.data
  } catch (error) {
    console.log(error)
    return null
  } finally {
    clueOptionsLoading.value = false
  }
}

const handleUpdateClueIds = (ids: number[]) => {
  formData.value.clueIds = ids
  if (!formData.value.clueIds || !formData.value.clueIds.length) {
    clueList.value = []
    tableData.value = []
    return
  }
  setClueBaseInfo()
}
const setClueBaseInfo = () => {
  queryTableData()
  if (!formData.value.clueIds || !formData.value.clueIds.length) {
    clueList.value = []
    return
  }
  const ids = formData.value.clueIds
  const list = clueList.value

  if (!expandNames.value.length) {
    expandNames.value.push(ids[0])
  }

  const unUsedList = list.filter((e) => !ids.includes(e.id))
  unUsedList.forEach((e) => {
    const index = list.findIndex((item) => item.id === e.id)
    if (index === -1) return
    list.splice(index, 1)
  })

  ids.forEach((e) => {
    if (list.find((item) => item.id === e)) return
    queryClueInfo(e).then((data) => {
      if (!data) return
      if (!formData.value.clueIds.includes(e)) return
      list.push(data)
    })
  })
}
const documentTypeOptions = shallowRef<DicTreeModel[]>([])
const queryDocumentTypeOptions = async () => {
  try {
    const [error, res] = await sendRequest<HttpResponse<DicTreeModel[]>>({
      module: 'dic',
      api: 'getTree',
      override: {
        params: {
          dicCode: 'A37'
        }
      }
    })

    if (error) throw error
    if (res.code !== 0) throw new Error(res.msg)
    documentTypeOptions.value = res.data[0] ? res.data[0].children || [] : []
  } catch (error) {
    console.error(error)
  }
}

const tableData = ref<CollectingTableRowModel[]>([])
const tableLoading = ref(false)
const columns: DataTableColumns<CollectingTableRowModel> = [
  {
    title: '序号',
    key: 'index',
    width: 80,
    align: 'center',
    render: (_, index) => index + 1
  },
  {
    title: '征集品名称',
    key: 'itemName'
  },
  {
    title: '类型',
    key: 'itemTypeName'
  },
  {
    title: '征集方式',
    key: 'collectTypeName'
  },
  {
    title: '接收时间',
    key: 'receiveTime'
  },
  {
    title: '接收人',
    key: 'receiveUser'
  },
  {
    title: '操作',
    key: 'action',
    width: 200,
    align: 'center',
    fixed: 'right',
    render: (e) => [
      h(
        NButton,
        {
          color: '#6CB187',
          quaternary: true,
          size: 'small',
          onClick: () => {
            router.push({
              name: 'collectWDetail',
              params: {
                id: e.id
              },
              query: {
                type: 'detail',
                redirect: route.fullPath,
                fromBatchEdit: 'true'
              }
            })
          }
        },
        { default: () => '详情' }
      )
      // h(
      //   NButton,
      //   { color: '#FD4A29', quaternary: true, size: 'small', onClick: () => handleDelete(e.id) },
      //   { default: () => '删除' }
      // )
    ]
  }
]
const queryTableData = async () => {
  const hasIds = formData.value.clueIds && formData.value.clueIds.length

  try {
    if (!hasIds) return (tableData.value = [])

    tableLoading.value = true
    const [error, res] = await sendRequest<HttpResponsePagination<CollectingTableRowModel>>({
      module: 'batch',
      api: isEdit ? 'collectingEditList' : 'collectingList',
      override: {
        data: {
          clueIds: formData.value.clueIds,
          batchId: isEdit ? route.params.id : null,
          limit: 100000000
        }
      }
    })
    if (error) throw error
    if (res.code !== 0) throw new Error(res.msg)

    tableData.value = res.data.list
  } catch (error) {
    console.log(error)
  } finally {
    tableLoading.value = false
  }
}

onMounted(async () => {
  await checkEdit()
  Promise.allSettled([queryClueOptions(), queryDocumentTypeOptions()])
})
onUnmounted(() => dialog.destroyAll())
onDeactivated(() => dialog.destroyAll())
</script>

<template>
  <div class="add-batch">
    <div class="batch-title">批次信息</div>
    <NForm
      :disabled="submitLoading"
      :model="formData"
      ref="formInst"
      label-placement="left"
      require-mark-placement="left"
      label-width="100rem"
      class="ab-card"
    >
      <NFormItem
        label="批次名称："
        path="batchName"
        :rule="[
          { required: true, message: '批次名称为必填项，请输入', trigger: 'blur' },
          {
            required: true,
            trigger: ['blur', 'input'],
            message: '批次名称不能超过200字',
            validator: (_, value) => (value ? value.length <= 200 : true)
          }
        ]"
      >
        <NInput
          placeholder="请输入"
          v-model:value="formData.batchName"
        />
      </NFormItem>
      <NFormItem
        label="线索名称："
        path="clueIds"
        :rule="{ required: true, message: '线索名称为必填项，请选择', type: 'array' }"
      >
        <NSelect
          placeholder="请选择"
          :options="(clueOptions as unknown as SelectOption[])"
          multiple
          label-field="clueName"
          value-field="id"
          filterable
          :value="formData.clueIds"
          @update:value="handleUpdateClueIds"
          @update-show="handleClueNameVisible"
        />
      </NFormItem>
      <NFormItem label="描述：">
        <NInput
          type="textarea"
          placeholder="请输入"
          rows="1"
          v-model:value="formData.description"
        />
      </NFormItem>
      <!-- <NFormItem label="开始时间：">
        <NDatePicker input-readonly
          placeholder="请选择"
          style="flex: 1"
          format="yyyy-MM-dd"
          type="date"
          v-model:formatted-value="formData.startDate"
        />
      </NFormItem>
      <NFormItem label="结束时间：">
        <NDatePicker input-readonly
          placeholder="请选择"
          style="flex: 1"
          :disabled="!formData.startDate"
          format="yyyy-MM-dd"
          type="date"
          v-model:formatted-value="formData.endDate"
          :is-date-disabled="(ts: number) => ts < new Date(formData.startDate as string).getTime()"
        />
      </NFormItem>
      <NFormItem
        label="代存期限："
        path="depositTerm"
        :rule="{
          trigger: ['blur', 'input'],
          message: '存期限不能超过100字',
          validator: (_, value) => (value ? value.length <= 100 : true)
        }"
      >
        <NInput
          placeholder="请输入"
          v-model:value="formData.depositTerm"
        />
      </NFormItem> -->
      <!-- <span style="padding-left: 100rem">
        带
        <span style="color: #fd4a29">*</span>
        为必填项
      </span> -->
    </NForm>

    <div
      v-show="clueList.length"
      class="br"
    ></div>

    <div
      v-show="clueList.length"
      class="batch-title"
    >
      线索信息
    </div>
    <NCollapse
      v-model:expanded-names="expandNames"
      style="--n-title-padding: 0 20rem; --n-divider-color: transparent"
    >
      <template #arrow></template>

      <NCollapseItem
        v-for="item in clueList"
        :key="item.id"
        :name="item.id"
      >
        <template #header>
          <span>{{ item.clueName }}</span>
          <NButton
            color="#6CB187"
            quaternary
            size="tiny"
          >
            点击{{ expandNames.includes(item.id) ? '收起' : '展开' }}
          </NButton>
        </template>

        <NForm
          class="ab-card columns-2"
          label-placement="left"
          label-width="100rem"
          disabled
        >
          <NFormItem label="线索名称：">
            <NInput
              placeholder="/"
              v-model:value="item.clueName"
            />
          </NFormItem>
          <NFormItem label="移交人：">
            <NInput
              placeholder="/"
              v-model:value="item.transferUser"
            />
          </NFormItem>
          <NFormItem label="接收人：">
            <NInput
              placeholder="/"
              v-model:value="item.receiveUser"
            />
          </NFormItem>
          <NFormItem label="接收时间：">
            <NDatePicker
              input-readonly
              placeholder="/"
              style="flex: 1"
              format="yyyy-MM-dd HH:mm:ss"
              v-model:formatted-value="item.receiveTime"
            />
          </NFormItem>
          <NFormItem label="姓名：">
            <NInput
              placeholder="/"
              v-model:value="item.userName"
            />
          </NFormItem>
          <NFormItem label="单位：">
            <NInput
              placeholder="/"
              v-model:value="item.dept"
            />
          </NFormItem>
          <NFormItem label="联系方式：">
            <NInput
              placeholder="/"
              v-model:value="item.phone"
            />
          </NFormItem>
          <NFormItem label="提交时间：">
            <NDatePicker
              input-readonly
              placeholder="/"
              style="flex: 1"
              format="yyyy-MM-dd HH:mm:ss"
              v-model:formatted-value="item.commitTime"
            />
          </NFormItem>
          <NFormItem label="证件类型：">
            <NSelect
              :options="(documentTypeOptions as unknown as SelectOption[])"
              label-field="name"
              value-field="name"
              placeholder="/"
              v-model:value="item.idTypeName"
            />
          </NFormItem>
          <NFormItem label="证件号：">
            <NInput
              placeholder="请输入"
              v-model:value="item.idNo"
            />
          </NFormItem>
        </NForm>
      </NCollapseItem>
    </NCollapse>

    <div class="br"></div>

    <div class="batch-title">物品信息</div>
    <div class="ab-card batch-table">
      <NDataTable
        :data="tableData"
        :columns="columns"
        :loading="tableLoading"
        max-height="200rem"
        bordered
      />
    </div>
  </div>

  <FixedAction>
    <div class="add-batch-buttons">
      <NButton
        color="#999999"
        ghost
        :disabled="submitLoading"
        @click="routeReplace"
      >
        取消
      </NButton>

      <NButton
        color="#5FB17F"
        :disabled="submitLoading"
        :loading="submitLoading"
        @click="handleSubmit"
      >
        确定
      </NButton>
    </div>
  </FixedAction>
</template>

<style scoped lang="scss">
.add-batch {
  min-height: 100%;
  padding: 15rem 0 110rem;
  background-color: #f0efee;

  :deep(.n-data-table__pagination) {
    justify-content: flex-start;
  }

  .br {
    position: relative;
    width: 100%;
    padding: 30rem 0;

    &::after {
      content: '';
      position: absolute;
      width: 100%;
      top: 50%;
      left: 0;
      border-top: 1px dotted #bc9e70;
      transform: translateY(-50%);
    }
  }

  .ab-card {
    padding: 20rem;
    background-color: #e1e1e1;
  }

  .n-form {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 0 60rem;

    &.columns-2 {
      grid-template-columns: repeat(2, 1fr);
      margin-top: 0;
    }
  }

  .batch-title {
    font-size: 26rem;
    margin-bottom: 30rem;
    color: #048c5e;
    line-height: 1;
  }

  .batch-table {
    display: flex;
    flex-direction: column;
  }
}

.add-batch-buttons {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0 16rem;

  .n-button {
    width: 100rem;
    height: 50rem;
  }
}
</style>
